package com.bestcem.xm.award.grpc.service;

import com.bestcem.bp.grpc.v1.base.FileInfo;
import com.bestcem.xm.award.controller.convert.WinDataConvert;
import com.bestcem.xm.award.grpc.v1.common.BaseTime;
import com.bestcem.xm.award.grpc.v1.enums.AwardLevelEnum;
import com.bestcem.xm.award.grpc.v1.services.*;
import com.bestcem.xm.award.service.bo.award.AwardAwardBO;
import com.bestcem.xm.award.service.dto.AwardDataDTO;
import com.bestcem.xm.award.service.dto.awardaward.GetAwardDTO;
import com.bestcem.xm.award.service.impl.AwardDispatcher;
import com.bestcem.xm.award.util.MoneyUtil;
import com.bestcem.xm.common.core.domain.web.RpcStatusResult;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.uitls.DateUtil;
import com.bestcem.xm.common.core.uitls.GRpcUtil;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;

@GrpcService
@Slf4j
public class AwardAwardGrpcService extends AwardServiceGrpc.AwardServiceImplBase {
    @Resource
    private AwardDispatcher awardAwardService;

    @Override
    public void getAward(GetAwardRequest request, StreamObserver<GetAwardResponse> responseObserver) {
        GetAwardResponse.Builder builder = GetAwardResponse.newBuilder();

        GetAwardDTO getAwardDTO = new GetAwardDTO();
        getAwardDTO.setId(request.getId());
        getAwardDTO.setNeedWin(request.getNeedWin());
        // 参数校验
        String msg = validateParam(getAwardDTO);
        if (!Objects.isNull(msg)) {
            builder.setStatus(RpcStatusResult.error(msg));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        //业务层进行查询
        ServiceResult<AwardDataDTO> result = awardAwardService.getAward(getAwardDTO);
        log.info("查询奖励{}", result);
        if (result.isSuccess()) {
            AwardDataDTO data = result.getData();
            builder.setStatus(RpcStatusResult.success());
            builder.setAward(awardAwardToAwardData(data.getAward()));
            builder.setWinData(WinDataConvert.winDataBOToWinData(data.getWinData()));
        } else {
            builder.setStatus(RpcStatusResult.error(result.getMsg()));
        }
        log.info("查询奖励转换后{}", builder);
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    private String validateParam(Object param) {
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return violation.getMessage();
        }
        return null;
    }

    /**
     * AwardAward 转 AwardData
     *
     * @param awardAward 数据库数据
     * @return grpc接口数据
     */
    private Award awardAwardToAwardData(AwardAwardBO awardAward) {
        if (Objects.isNull(awardAward)) {
            return null;
        }
        Award.Builder builder = Award.newBuilder();
        //主键
        builder.setId(awardAward.getId());
        //问卷id
        builder.setProjectId(awardAward.getProjectId());
        //奖励类型
        builder.setTypeValue(awardAward.getTType());
        //奖励状态
        builder.setStatusValue(awardAward.getStatus());
        //机构id
        builder.setOrgId(awardAward.getOrgId());
        //奖励名称
        builder.setName(awardAward.getName());
        //奖励基本配置转换
        if (Objects.nonNull(awardAward.getBasic())) {
            builder.setBasic(basicToAwardBasic(awardAward.getBasic()));
        }
        //奖项配置转换
        if (!CollectionUtils.isEmpty(awardAward.getAwards())) {
            awardAward.getAwards().stream().filter(Objects::nonNull).map(this::awardToDrawAward).forEach(builder::addDrawAwards);
        }
        //配送方式转换
        if (Objects.nonNull(awardAward.getIssue())) {
            builder.setIssue(issueToAwardIssue(awardAward.getIssue()));
        }
        //页面配置转换
        if (Objects.nonNull(awardAward.getPage())) {
            builder.setPage(pageToAwardPage(awardAward.getPage()));
        }
        //奖励规则转换
        if (Objects.nonNull(awardAward.getRule())) {
            builder.setRule(ruleToAwardRule(awardAward.getRule()));
        }
        //奖励是否已激活
        if (Objects.nonNull(awardAward.getActivated())) {
            builder.setActivated(awardAward.getActivated());
        }
        //实际领取奖励的数量
        if (Objects.nonNull(awardAward.getCurCount())) {
            builder.setCurrentCount(awardAward.getCurCount());
        }
        //钱包活动id
        if (Objects.nonNull(awardAward.getActivityId())) {
            builder.setActivityId(awardAward.getActivityId());
        }
        //清算标志
        if (Objects.nonNull(awardAward.getSettlement())) {
            builder.setSettlementStatusValue(awardAward.getSettlement());
        }
        builder.setBaseTime(getBaseTime(awardAward));
        return builder.build();
    }

    /**
     * 奖励基本配置转换
     *
     * @param basic 数据库basic数据
     * @return grpc接口basic数据
     */
    private AwardBasic basicToAwardBasic(AwardAwardBO.Basic basic) {
        if (Objects.isNull(basic)) {
            return null;
        }
        AwardBasic.Builder builder = AwardBasic.newBuilder();
        // 奖励开始时间
        if (Objects.nonNull(basic.getStartTime())) {
            builder.setStartTime(DateUtil.getTimestamp(basic.getStartTime()));
        }
        // 奖励结束时间
        if (Objects.nonNull(basic.getStopTime())) {
            builder.setEndTime(DateUtil.getTimestamp(basic.getStopTime()));
        }
        //  所有人抽奖次数限制 红包个数
        if (Objects.nonNull(basic.getTotalCount())) {
            builder.setTotalCount(basic.getTotalCount());
        }
        // 红包详情, 会显示在领取红包的入账通知和详情页，比如：问卷红包
        if (Objects.nonNull(basic.getName())) {
            builder.setName(basic.getName());
        }

        // 0: 百分百获得红包; N(>1): 概率红包,预计总参与人数
        if (Objects.nonNull(basic.getProbability())) {
            builder.setProbability(Optional.of(basic.getProbability()).map(Long::intValue).orElse(0));
        }
        // 红包总金额
        if (Objects.nonNull(basic.getTotalAmount())) {
            builder.setTotalAmount(Optional.ofNullable(MoneyUtil.yuanToCent(basic.getTotalAmount())).map(Long::intValue).orElse(0));
        }
        // 可选, 单个红包金额, 单位元, 普通红包必选,包含小数、整数、""
        if (Objects.nonNull(basic.getSinAmount())) {
            builder.setSingleAmount(Optional.ofNullable(MoneyUtil.yuanToCent(basic.getSinAmount())).map(Long::intValue).orElse(0));
        }
        // 红包页面展示的公司名称
        if (Objects.nonNull(basic.getDisplayName())) {
            builder.setDisplayName(basic.getDisplayName());
        }
        // 红包页面展示的logo
        if (Objects.nonNull(basic.getDisplayLogoPath())) {
            FileInfo.Builder fileBuilder = FileInfo.newBuilder();
            // 红包页面展示的logo的id
            if (Objects.nonNull(basic.getDisplayLogoId())) {
                fileBuilder.setId(basic.getDisplayLogoId());
            }
            // 红包页面展示的logo的的路径
            if (Objects.nonNull(basic.getDisplayLogoPath())) {
                fileBuilder.setUrl(basic.getDisplayLogoPath());
            }
            builder.setDisplayLogo(fileBuilder.build());
        }
        return builder.build();
    }

    /**
     * 抽奖奖励配置转换
     *
     * @param award 数据库抽奖配置
     * @return grpc抽奖配置
     */
    private DrawAward awardToDrawAward(AwardAwardBO.Award award) {
        if (Objects.isNull(award)) {
            return null;
        }
        DrawAward.Builder builder = DrawAward.newBuilder();
        // 奖项等级
        if (Objects.nonNull(award.getLevel())) {
            builder.setLevel(AwardLevelEnum.AwardLevel.forNumber(award.getLevel()));
        }
        // 奖项名称，列表内唯一
        if (Objects.nonNull(award.getName())) {
            builder.setName(award.getName());
        }
        // 奖项描述
        if (Objects.nonNull(award.getDesc())) {
            builder.setDesc(award.getDesc());
        }
        // 中奖概率
        if (Objects.nonNull(award.getProb())) {
            builder.setProbability(award.getProb().toPlainString());
        }
        // 奖项图片
        if (Objects.nonNull(award.getImg())) {
            builder.setImgUrl(award.getImg());
        }
        // 奖项数量
        if (Objects.nonNull(award.getNum())) {
            builder.setNum(award.getNum());
        }
        return builder.build();
    }

    /**
     * 抽奖发放相关信息 转换
     *
     * @param issue 数据库抽奖发放数据
     * @return grpc抽奖发放
     */
    private AwardIssue issueToAwardIssue(AwardAwardBO.Issue issue) {
        if (Objects.isNull(issue)) {
            return null;
        }
        AwardIssue.Builder builder = AwardIssue.newBuilder();
        // 兑奖操作提示
        if (Objects.nonNull(issue.getTip())) {
            builder.setTip(issue.getTip());
        }
        // 发放方式 @see com.bestcem.xm.award.util.enums.AwardIssueTypeEnum
        if (Objects.nonNull(issue.getMethod())) {
            builder.setTypeValue(issue.getMethod());
        }
        // 可选,兑奖码前缀
        if (Objects.nonNull(issue.getPrefix())) {
            builder.setPrefix(issue.getPrefix());
        }
        // 可选,短信通知内容
        if (Objects.nonNull(issue.getSms())) {
            builder.setSmsContent(issue.getSms());
        }
        return builder.buildPartial();
    }

    /**
     * 奖项页面配置信息转换
     *
     * @param page 数据库 奖项页面配置
     * @return grpc奖项页面配置
     */
    private AwardPage pageToAwardPage(AwardAwardBO.Page page) {
        if (Objects.isNull(page)) {
            return null;
        }
        AwardPage.Builder builder = AwardPage.newBuilder();
        // 跳转链接url配置
        if (Objects.nonNull(page.getUrl())) {
            builder.setUrl(page.getUrl());
        }
        // 附件列表
        if (!CollectionUtils.isEmpty(page.getAttachments())) {
            page.getAttachments().stream().filter(Objects::nonNull).map(this::attachmentToFileInfo).forEach(builder::addFileInfos);
        }
        // css自定义代码
        if (Objects.nonNull(page.getGcss())) {
            builder.setCssScript(page.getGcss());
        }
        // css自定义代码路径
        if (Objects.nonNull(page.getGcssFp())) {
            builder.setCssFilePath(page.getGcssFp());
        }
        // css自定义代码路径id
        if (Objects.nonNull(page.getGcssId())) {
            builder.setCssId(page.getGcssId());
        }
        // 奖励页自定义代码
        if (Objects.nonNull(page.getTemplate())) {
            builder.setTemplateScript(page.getTemplate());
        }
        // 奖励页自定义代码路径
        if (Objects.nonNull(page.getTemplateFp())) {
            builder.setTemplateFilePath(page.getTemplateFp());
        }
        // 奖励页自定义代码路径id
        if (Objects.nonNull(page.getTemplateId())) {
            builder.setTemplateId(page.getTemplateId());
        }
        // 手机端页面配置
        if (Objects.nonNull(page.getMobile())) {
            builder.setPhone(pageFrontToAwardPageFront(page.getMobile()));
        }
        // 电脑端页面配置
        if (Objects.nonNull(page.getPc())) {
            builder.setPc(pageFrontToAwardPageFront(page.getPc()));
        }
        return builder.build();
    }

    /**
     * 奖项页面附件信息转换
     *
     * @param attachment 数据库 奖项附件配置
     * @return grpc奖项附件配置
     */
    private FileInfo attachmentToFileInfo(AwardAwardBO.Attachment attachment) {
        if (Objects.isNull(attachment)) {
            return null;
        }
        FileInfo.Builder builder = FileInfo.newBuilder();
        // 附件名称
        if (Objects.nonNull(attachment.getFileName())) {
            builder.setName(attachment.getFileName());
        }
        // 附件路径
        if (Objects.nonNull(attachment.getFilePath())) {
            builder.setUrl(attachment.getFilePath());
        }
        // 附件id
        if (Objects.nonNull(attachment.getId())) {
            builder.setId(attachment.getId());
        }
        return builder.build();
    }

    /**
     * 前端页面配置转换
     *
     * @param pageFront 数据库 前端页面配置
     * @return grpc 前端页面配置
     */
    private AwardFront pageFrontToAwardPageFront(AwardAwardBO.PageFront pageFront) {
        if (Objects.isNull(pageFront)) {
            return null;
        }
        AwardFront.Builder builder = AwardFront.newBuilder();
        // 前端页面背景配置
        if (Objects.nonNull(pageFront.getBg())) {
            builder.setBackground(pageFrontBgToAwardPageFrontBg(pageFront.getBg()));
        }
        // 二维码配置
        if (Objects.nonNull(pageFront.getQr())) {
            builder.setQrCode(pageFrontQrToAwardPageFrontQr(pageFront.getQr()));
        }
        // 结束语内容
        if (Objects.nonNull(pageFront.getText())) {
            builder.setText(pageFrontTextToAwardPageFrontTxt(pageFront.getText()));
        }
        // logo配置
        if (Objects.nonNull(pageFront.getLogo())) {
            builder.setLogo(pageFrontLogoToAwardPageFrontLog(pageFront.getLogo()));
        }
        return builder.build();
    }

    /**
     * 前端页面背景配置转换
     *
     * @param pageFrontBg 数据库 前端页面背景配置
     * @return grpc 前端页面背景配置
     */
    private AwardFrontBg pageFrontBgToAwardPageFrontBg(AwardAwardBO.PageFrontBg pageFrontBg) {
        if (Objects.isNull(pageFrontBg)) {
            return null;
        }
        AwardFrontBg.Builder builder = AwardFrontBg.newBuilder();
        // 背景颜色，color与id+path只能二选一，有color就不存储id+path
        if (Objects.nonNull(pageFrontBg.getColor())) {
            builder.setColor(pageFrontBg.getColor());
        }
        // 图片id
        if (Objects.nonNull(pageFrontBg.getId())) {
            builder.setId(pageFrontBg.getId());
        }
        // 图片路径
        if (Objects.nonNull(pageFrontBg.getPath())) {
            builder.setPath(pageFrontBg.getPath());
        }
        return builder.build();
    }

    /**
     * 前端页面二维码配置转换
     *
     * @param pageFrontQr 数据库 前端页面二维码配置
     * @return grpc 前端页面二维码配置
     */
    private AwardFrontQr pageFrontQrToAwardPageFrontQr(AwardAwardBO.PageFrontQr pageFrontQr) {
        if (Objects.isNull(pageFrontQr)) {
            return null;
        }
        AwardFrontQr.Builder builder = AwardFrontQr.newBuilder();
        // 图片id
        if (Objects.nonNull(pageFrontQr.getId())) {
            builder.setId(pageFrontQr.getId());
        }
        // 图片路径
        if (Objects.nonNull(pageFrontQr.getPath())) {
            builder.setPath(pageFrontQr.getPath());
        }
        return builder.build();
    }

    /**
     * 前端页面文字配置转换
     *
     * @param pageFrontText 数据库 前端页面文字配置转换
     * @return grpc 前端页面文字配置转换
     */
    private AwardFrontTxt pageFrontTextToAwardPageFrontTxt(AwardAwardBO.PageFrontText pageFrontText) {
        if (Objects.isNull(pageFrontText)) {
            return null;
        }
        AwardFrontTxt.Builder builder = AwardFrontTxt.newBuilder();
        // 文字颜色
        if (Objects.nonNull(pageFrontText.getColor())) {
            builder.setColor(pageFrontText.getColor());
        }
        // 文本内容
        if (Objects.nonNull(pageFrontText.getData())) {
            builder.setContent(pageFrontText.getData());
        }
        // 是否加粗
        if (Objects.nonNull(pageFrontText.getBold())) {
            builder.setBold(pageFrontText.getBold());
        }
        // 是否倾斜
        if (Objects.nonNull(pageFrontText.getItalic())) {
            builder.setItalic(pageFrontText.getItalic());
        }
        // 是否下划线
        if (Objects.nonNull(pageFrontText.getUnderline())) {
            builder.setUnderline(pageFrontText.getUnderline());
        }
        // 文字大小
        if (Objects.nonNull(pageFrontText.getSize())) {
            builder.setSize(pageFrontText.getSize());
        }
        return builder.build();
    }

    /**
     * 前端页面logo配置转换
     *
     * @param pageFrontLogo 数据库 前端页面logo配置转换
     * @return grpc 前端页面logo配置转换
     */
    private AwardFrontLogo pageFrontLogoToAwardPageFrontLog(AwardAwardBO.PageFrontLogo pageFrontLogo) {
        if (Objects.isNull(pageFrontLogo)) {
            return null;
        }
        AwardFrontLogo.Builder builder = AwardFrontLogo.newBuilder();
        // 图片id
        if (Objects.nonNull(pageFrontLogo.getId())) {
            builder.setId(pageFrontLogo.getId());
        }
        // 图片路径
        if (Objects.nonNull(pageFrontLogo.getPath())) {
            builder.setPath(pageFrontLogo.getPath());
        }
        // 缩放比例
        if (Objects.nonNull(pageFrontLogo.getScale())) {
            builder.setScale(pageFrontLogo.getScale());
        }
        // 图片位置
        if (Objects.nonNull(pageFrontLogo.getPos())) {
            builder.setPos(pageFrontLogo.getPos());
        }
        return builder.build();
    }

    /**
     * 奖励规则配置
     *
     * @param rule 数据库 奖励规则配置
     * @return grpc 奖励规则配置
     */
    private AwardLimitRule ruleToAwardRule(AwardAwardBO.Rule rule) {
        if (Objects.isNull(rule)) {
            return null;
        }
        AwardLimitRule.Builder builder = AwardLimitRule.newBuilder();
        // 可选,答题时间限制
        if (Objects.nonNull(rule.getTime())) {
            builder.setTime(rule.getTime());
        }
        // 可选, 单人抽奖次数限制
        if (Objects.nonNull(rule.getDraw())) {
            builder.setDraw(rule.getDraw());
        }
        // 可选,单人中奖次数限制 单微信号领取次数限制
        if (Objects.nonNull(rule.getWin())) {
            builder.setWin(rule.getWin());
        }
        // 可选 账户访问限制
        if (Objects.nonNull(rule.getAccount())) {
            builder.setAccount(rule.getAccount());
        }
        // 可选 设备访问次数限制
        if (Objects.nonNull(rule.getDevice())) {
            builder.setDevice(rule.getDevice());
        }
        // 可选 ip访问次数限制
        if (Objects.nonNull(rule.getIp())) {
            builder.setIp(rule.getIp());
        }
        // 可选，单日领取次数限制
        if (Objects.nonNull(rule.getDay())) {
            builder.setDay(rule.getDay());
        }
        // 可选，奖励结束是否停止投放 is stop deliver
        if (Objects.nonNull(rule.getStopDeliver())) {
            builder.setStopDeliver(rule.getStopDeliver());
        }
        // 可选，设置的问卷分值
        if (Objects.nonNull(rule.getSscore())) {
            builder.setScore(rule.getSscore());
        }
        return builder.build();
    }

    /**
     * 从奖励提取baseModel配置
     *
     * @param awardAward 数据库BaseTime
     * @return grpc BaseTime
     */
    private BaseTime getBaseTime(AwardAwardBO awardAward) {
        if (Objects.isNull(awardAward)) {
            return null;
        }
        BaseTime.Builder builder = BaseTime.newBuilder();
        // 创建时间
        if (Objects.nonNull(awardAward.getCreatedDate())) {
            builder.setCreateTime(DateUtil.getTimestamp(awardAward.getCreatedDate()));
        }
        // 更新时间
        if (Objects.nonNull(awardAward.getUpdatedDate())) {
            builder.setUpdateTime(DateUtil.getTimestamp(awardAward.getUpdatedDate()));
        }
        return builder.build();
    }
}
